﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using ClosedXML.Excel;
using Haimen.Excel;

namespace Haimen.Func2;

internal class MonthInputCollector(
    ExcelFileUtils excelUtil) {

  public MonthStoreIn[] Collect(AppEnvPath env) {
    CopyCfg[] cfgList = ReadCopyConfig(env);
    return CollectInput(env, cfgList);
  }

  //t:HmLab.Func2.LbReadCopyConfig
  CopyCfg[] ReadCopyConfig(AppEnvPath path) {
    const string cfgFile = "path.xlsx";
    var ResolveCfg = () => {
      string devCfg = path.InDev(cfgFile);
      if (File.Exists(devCfg)) {
        Console.WriteLine($"检测到dev：{devCfg}");
        return devCfg;
      }
      return path.ResFunc2(cfgFile);
    };

    string cfgPath = ResolveCfg();
    Console.WriteLine(cfgPath);

    using FileStream stream = _excelUtil.OpenRead(cfgPath);
    using XLWorkbook configBook = new(stream);

    IXLWorksheet sheet = configBook.Worksheets.Single();
    //Console.WriteLine(sheet.Name);

    int lastRow = sheet.LastRowUsed().RowNumber();
    return Enumerable.Range(1, lastRow)
      .Select(r => ParseRow(sheet, r))
      .ToArray();
  }

  record CopyCfg(string File, string Sheet, string Range, int Sort);
  CopyCfg ParseRow(IXLWorksheet sheet, int num) {
    IXLRow row = sheet.Row(num);
    var CellStr = (int c) => row.Cell(c).GetString();

    var ParseRange = () => {
      string rangeStr = CellStr(3);
      string[] rangeSplit = rangeStr.Split(':');
      if (rangeSplit.Length == 1) {
        return $"A1:{rangeStr}";
      }

      Debug.Assert(rangeSplit.Length == 2);
      string start = rangeSplit[0];
      string end = rangeSplit[1];
      if (string.IsNullOrWhiteSpace(start)) {
        return $"A1:{end}";
      }

      Debug.Assert(end.Length > 1);
      return rangeStr;
    };

    string range = ParseRange();
    return new(CellStr(1), CellStr(2), range, num);
  }

  //t:HmLab.Func2.LbCollectMonthInput
  MonthStoreIn[] CollectInput(AppEnvPath path, CopyCfg[] cfgList) {
    string storeDir = path.In("店铺分表");
    Dictionary<string, CopyCfg> cfgDict = cfgList.ToDictionary(c => c.File);

    var MakeInput = (string p, string file) => {
      (string month, string key) = GetStoreInfo(file);
      CopyCfg cfg = cfgDict[key];
      MonthStoreIn input = new(p, month, cfg.Range, cfg.Sheet);
      return (input, sort: cfg.Sort);
    };

    return Directory.GetFiles(storeDir)
      .Select(p => (path: p, file: Path.GetFileName(p)))
      .Where(tp => !tp.file.StartsWith("~$"))
      .Select(tp => MakeInput(tp.path, tp.file))
      .OrderBy(tp => tp.sort)
      .Select(tp => tp.input)
      .ToArray();
  }

  (string, string) GetStoreInfo(string file) {
    int index = file.IndexOf("_人民币(");
    string[] infoSplit = file[..index].Split('_');

    string date = infoSplit[0];
    var GetMonth = () => {
      int start = date.IndexOf('年') + 1;
      int end = date.LastIndexOf("期月报");
      return date[start..end] + "月";
    };

    string key = infoSplit[2];
    return (GetMonth(), key);
  }

  readonly ExcelFileUtils _excelUtil = excelUtil;
}

internal record MonthStoreIn(string Path, string Month, string Range, string ToSheet);
